home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Floppyshop 2
/
Floppyshop - 2.zip
/
Floppyshop - 2.iso
/
art&graf.ix
/
art-0039
/
generatr
/
generatr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-16
|
23KB
|
755 lines
/****************************************************************
* GENERATR.C | The Degas Elite Image Toolkit | December 9, 1988 *
* ------------------------------------------------------------- *
* Programmed by Robert M. Birmingham and Richard C. Leinecker. *
****************************************************************/
#include <obdefs.h>
#include <define.h>
#include <osbind.h>
#include <gemdefs.h>
/* define the array positions for each box... */
#define SCRN1 0
#define SCRN2 1
#define SCRN3 2
#define SCRN4 3
#define SCRN5 4
#define SCRN6 5
#define SCRN7 6
#define SCRN8 7
#define CUTIMAGE 8
#define TO_C 9
#define TO_ASM 10
#define TO_GFA 11
#define TO_DATA 12
/* define mixinum and maximum for window redraw code... */
#define maximum(x,y) (((x) > (y)) ? (x) : (y))
#define minimum(x,y) (((x) < (y)) ? (x) : (y))
/* define the type of window to use... */
#define WI_KIND ( CLOSER | MOVER | NAME | FULLER )
/* global application ID number */
extern int gl_apid;
/* arrays for GEM bindings... */
int contrl[12];
int intin[128];
int ptsin[128];
int intout[128];
int ptsout[128];
int work_in[11];
int work_out[57];
char pathname[128]; /* pathname for file selector */
char filename[128]; /* filename for saving the image */
int handle; /* workstation handle */
int menu_id; /* accessory menu ID number */
int degas_id; /* application ID of Degas Elite */
int wi_handle; /* calculator window handle */
int gr_hwchar; /* width of a character cell */
int gr_hhchar; /* height of a character cell */
int mx, my, button; /* mouse position and button */
int rx1,ry1,rx2,ry2; /* rectangle for cut image coord */
int xwork, ywork; /* position of window work area */
int wwork, hwork; /* width and height of work area */
int ax, ay, aw, ah; /* accessory window coordinates */
int rez; /* current system resolution */
int cutflag; /* buffer undefined/defined flag */
int cur_screen; /* currently selected screen box */
int msgbuff[16]; /* evnt_multi() message buffer */
long *scrn_pntrs; /* pointer to screen pointer list */
long scrn_array[8]; /* holds DE's screen pointers 1-8 */
long temp_scrn; /* pointer to DE's work screen */
long undo_scrn; /* pointer to DE's UNDO buffer */
char image_names[800]; /* array for array names entered */
int names; /* number of array names entered */
/* declare an array of structures to hold the box information... */
struct boxdefs
{
int x, y;
int w, h;
char *string;
} boxes[] = {
1, 0, 11, 1, " Screen #1",
1, 2, 11, 1, " Screen #2",
1, 4, 11, 1, " Screen #3",
1, 6, 11, 1, " Screen #4",
14, 0, 11, 1, " Screen #5",
14, 2, 11, 1, " Screen #6",
14, 4, 11, 1, " Screen #7",
14, 6, 11, 1, " Screen #8",
1, 8, 24, 1, "Cut Image",
1, 10, 24, 1, "Buffer to C",
1, 12, 24, 1, "Buffer to Assembly",
1, 14, 24, 1, "Buffer to GFA Basic",
1, 16, 24, 1, "Buffer to Data File"
};
/* Initialize the key enabled/disabled bitmapped fields... */
int boxflags[] = { 0x0100, 0x1f00 };
main()
{
initialize(); /* initialize the accessory */
do_event(); /* handle the message events */
}
/********************************************************
* do_event(): *
* This routine waits for an event, then calls a routine *
* to handle the message event that was returned. *
********************************************************/
do_event()
{
int i; /* miscellaneous variable */
int mx, my; /* mouse position variables */
int event; /* event returned by evnt_multi() */
graf_mouse( ARROW, 0x0L );
/* good accessories never die! */
while( TRUE )
{
/* wait for a message or button event */
event = evnt_multi( MU_BUTTON | MU_MESAG, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
msgbuff, 0, 0, &mx, &my,
&i, &i, &i, &i );
/* process the event returned */
if( event & MU_MESAG ) do_message( msgbuff );
if( event & MU_BUTTON ) check_box( mx, my );
}
} /* End of - do_event() */
/*************************************************************
* do_message(): *
* This routine calls the appropriate window event handler *
* with the information contained in the event message buffer *
*************************************************************/
do_message( msgbuff )
int msgbuff[];
{
switch( msgbuff[0] )
{
case AC_OPEN: acc_open( msgbuff ); break;
case AC_CLOSE: acc_close( msgbuff ); break;
case WM_MOVED: move_window(msgbuff); break;
case WM_CLOSED: close_window( msgbuff ); break;
case WM_NEWTOP: top_window( msgbuff ); break;
case WM_TOPPED: top_window( msgbuff ); break;
case WM_FULLED: show_authors( msgbuff ); break;
case WM_REDRAW: redraw( msgbuff ); break;
}
} /* End of - do_message() */
/*************************************
* acc_open(): *
* This routine opens the accessory *
* and ask DE for the necessary info. *
*************************************/
acc_open( msgbuff )
int msgbuff[];
{
static char not_found[] = "[1][|Could not find Degas Elite!][ Ok ]";
int i; /* miscellaneous variable */
int event; /* event returned by evnt_multi() */
int demsg[16]; /* buffer for degas elite messages */
/* return if the open command is not for us! */
if( msgbuff[4] != menu_id ) return(0);
/* if the window is already open, just top it and leave! */
if( wi_handle != -1 )
{
wind_set( wi_handle, WF_TOP, 0, 0, 0, 0 );
return(0);
}
/* otherwise, try to find Degas Elite and get it's ID # */
degas_id = appl_find( "DEGELITE" );
/* leave if an invalid ID # is returned */
if( degas_id < 0 )
{
form_alert( 1, not_found );
return(0);
}
/* Make sure DE is there! */
demsg[0] = 0xDE00;
demsg[1] = gl_apid;
demsg[2] = 0;
i = appl_write( degas_id, 16, demsg );
/* wait for a reply from DE, or for a timer to elapse */
event = evnt_multi( MU_MESAG|MU_TIMER, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
demsg, 2000, 0,
&i, &i, &i, &i, &i, &i );
/* if the timer elapsed, then DE didn't respond! */
if( event & MU_TIMER )
{
form_alert( 1, not_found );
return(0);
}
/* I think it's ok to ignore if the message isn't of interest */
if( demsg[0] != 0xDE80 ) return(0);
/* otherwise, ask Degas Elite for the buffer pointers */
demsg[0] = 0xDE00;
demsg[1] = gl_apid;
demsg[2] = 0;
appl_write( degas_id, 16, demsg );
/* wait for a reply from DE */
do{ evnt_mesag( demsg ); } while( demsg[0] != 0xDE80 );
/* grab the pointer to the array of screen pointers */
scrn_pntrs = (long *)(((long)demsg[3] << 16) |
(((long)demsg[4]) & 0x0000ffffL));
/* copy the drawing screen pointers to my array */
scrn_array[ SCRN1 ] = scrn_pntrs[ 1 ];
scrn_array[ SCRN2 ] = scrn_pntrs[ 2 ];
scrn_array[ SCRN3 ] = scrn_pntrs[ 7 ];
scrn_array[ SCRN4 ] = scrn_pntrs[ 8 ];
scrn_array[ SCRN5 ] = scrn_pntrs[ 9 ];
scrn_array[ SCRN6 ] = scrn_pntrs[ 10 ];
scrn_array[ SCRN7 ] = scrn_pntrs[ 11 ];
scrn_array[ SCRN8 ] = scrn_pntrs[ 12 ];
/* get the addresses of the work buffers */
temp_scrn = scrn_pntrs[ 5 ];
undo_scrn = scrn_pntrs[ 6 ];
/*
** set the box flags to enabled/disabled depending
** on whether the screen buffer was allocated!
*/
boxflags[0] = boxflags[0] & 0xff00;
boxflags[1] = boxflags[1] & 0xff00;
for( i = 0; i < 8; i++ )
{
if( scrn_array[i] != 0L )
{
boxflags[0] = boxflags[0] | (1 << i);
boxflags[1] = boxflags[1] | (1 << i);
}
}
/* get the currently selected screen */
demsg[0] = 0xDE01;
demsg[1] = gl_apid;
demsg[2] = 0;
appl_write( degas_id, 16, demsg );
do{ evnt_mesag( demsg ); } while( demsg[0] != 0xDE81 );
/* adjust the screen number returned to ignore the work buffers */
if( demsg[3] < 3 )
cur_screen = demsg[3] - 1;
else
cur_screen = demsg[3] - 5;
/* put an asterisk in front of the screen string if not empty */
for( i = 0; i < 8; i++ )
{
if( scrn_array[i] != 0L )
{
if( search_blank( scrn_array[i] ) )
boxes[i].string[0] = '*';
else
boxes[i].string[0] = ' ';
}
}
/* open the accessory */
cutflag = 0;
open_vwork();
open_window();
} /* End of - acc_open() */
/**************************************
* acc_close(): *
* This routine closes the workstation *
**************************************/
acc_close( msgbuff )
int msgbuff[];
{
if( msgbuff[3] == menu_id && wi_handle != -1 )
{
v_clsvwk( handle );
wi_handle = -1;
}
}
/***********************************************************************
* move_window(): *
* This routine moves the window to the position specified in msgbuff[] *
***********************************************************************/
move_window( msgbuff )
int msgbuff[];
{
/* return if move message is not for my window */
if( msgbuff[3] != wi_handle ) return(0);
/* update the accessory position variables */
ax = msgbuff[4];
ay = msgbuff[5];
aw = msgbuff[6];
ah = msgbuff[7];
/* set the window position */
wind_set( msgbuff[3], WF_CURRXYWH, ax, ay, aw, ah );
/* call routine to store work area position in global variables */
get_workarea();
}
/************************************************************
* close_window(): *
* This routine closes the window and closes the workstation *
************************************************************/
close_window( msgbuff )
int msgbuff[];
{
/* return if the close message is not for this window */
if( msgbuff[3] != wi_handle ) return(0);
/* otherwise, close it! */
wind_close( wi_handle );
wind_delete( wi_handle );
v_clsvwk( handle );
wi_handle = -1;
}
/****************************************************
* top_window(): *
* This routine sets the accessory window to the top *
****************************************************/
top_window( msgbuff )
int msgbuff[];
{
/* return if the top command is not for my window */
if( msgbuff[3] != wi_handle ) return(0);
wind_set( wi_handle, WF_TOP, 0, 0, 0, 0 );
}
/*********************************************************
* show_authors(): *
* This routine resorts to some shameless self-promotion! *
*********************************************************/
show_authors( msgbuff )
int msgbuff[];
{
static char authors[] = "[1][The Degas Elite Image Generator|\
Written by|\
Robert M. Birmingham|\
and|\
Richard C. Leinecker][ Ok! ]";
/* return if the top command is not for my window */
if( msgbuff[3] != wi_handle ) return(0);
form_alert( 1, authors );
}
/*************************************************
* redraw(): *
* This routine redraws sections of the window by *
* stepping through the window rectangle list. *
*************************************************/
redraw( msgbuff )
int msgbuff[];
{
int w[4]; /* holds rectangle coord's from window list */
/* return if the redraw message isn't for this window */
if( msgbuff[3] != wi_handle ) return(0);
wind_update(1);
/* get the first rectangle from the window list */
wind_get( msgbuff[3], WF_FIRSTXYWH, &w[0], &w[1], &w[2], &w[3] );
while( w[2] && w[3] )
{
if( b_intersect( &msgbuff[4], w ) ) draw_window( w );
wind_get( msgbuff[3], WF_NEXTXYWH, &w[0], &w[1], &w[2], &w[3] );
}
wind_update(0);
} /* End of - redraw() */
/******************************************************
* get_workarea(): *
* This routine gets the window's work area dimensions *
******************************************************/
get_workarea()
{
wind_get( wi_handle, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork );
}
/**********************************************
* check_box(): *
* This routine processes the box index passed *
**********************************************/
check_box( mx, my )
int mx, my;
{
int i; /* miscellaneous */
int box_index; /* index of box selected */
int button; /* mouse button state */
/* see if the mouse was clicked on an accessory box */
if( ( box_index = scan_boxes( mx, my ) ) < 0 ) return(0);
/* do nothing if the box is the screen selected */
if( box_index == cur_screen ) return(0);
/* if the box is disabled then return */
if(((boxflags[cutflag] >> (box_index-SCRN1)) & 0x0001) == 0) return(0);
/* lock out AES messages */
wind_update(1);
/*
** set the clipping rectangle so the boxes
** won't be drawn off the edge of the screen
*/
set_clip( 0, 0, work_out[0], work_out[1], 1 );
/* highlight the box selected */
draw_box( box_index, 1 );
/* find out which box was pressed */
if( box_index >= SCRN1 && box_index <= SCRN8 )
{
draw_box( cur_screen, 0 );
cur_screen = box_index;
}
else if( box_index == CUTIMAGE )
{
cutflag = cut_image( scrn_array[cur_screen], cutflag );
for( i = TO_C; i <= TO_DATA; i++ )
{
if( i == cur_screen )
draw_box( i, 1 );
else
draw_box( i, 0 );
}
}
else
image( scrn_array[ cur_screen ], box_index );
/* wait for the mouse button to be released */
do{ graf_mkstate( &i, &i, &button, &i ); } while( button );
/* reset the box unless it's a 'screen' box */
if( box_index != cur_screen ) draw_box( box_index, 0 );
/* clear the clipping rectangle */
set_clip( 0, 0, work_out[0], work_out[1], 0 );
/* enable AES messages */
wind_update(0);
} /* End of - check_box() */
/**********************************************************
* scan_boxes(): *
* Returns the box under the mouse position passed, if any *
**********************************************************/
scan_boxes( x, y )
int x, y;
{
int i;
/* see if the mouse cursor is inside a box */
for( i = SCRN1; i <= TO_DATA; i++ )
{
if( x >= xwork + boxes[i].x &&
y >= ywork + boxes[i].y &&
x <= xwork + boxes[i].x + boxes[i].w &&
y <= ywork + boxes[i].y + boxes[i].h )
return(i);
}
return(-1);
} /* End of - scan_boxes() */
/*******************************************
* draw_window(): *
* This routine redraws the accesory window *
*******************************************/
draw_window( w )
int w[];
{
int i; /* general purpose variable */
int pxyarray[4]; /* used to clear the window */
int clip[4]; /* clipping rectangle to set */
/* set the clipping rectangle */
clip[0] = w[0];
clip[1] = w[1];
clip[2] = w[0] + w[2] - 1;
clip[3] = w[1] + w[3] - 1;
vs_clip( handle, 1, clip );
/* clear the work area */
pxyarray[0] = xwork;
pxyarray[1] = ywork;
pxyarray[2] = xwork + wwork - 1;
pxyarray[3] = ywork + hwork - 1;
/* set the various attributes for the box */
v_hide_c( handle );
vsf_color( handle, 0 );
vsf_interior( handle, 2 );
vsf_style( handle, 8 );
vr_recfl( handle, pxyarray );
/* redraw each box (highlight the active screen box) */
for( i = SCRN1; i <= TO_DATA; i++ )
{
if( i == cur_screen )
draw_box( i, 1 );
else
draw_box( i, 0 );
}
/* reset the clipping rectangle */
vs_clip( handle, 0, clip );
v_show_c( handle, 0 );
} /* End of - draw_window() */
/******************************************************************
* draw_box(): *
* This routine redraws the box whose array index number is passed *
******************************************************************/
draw_box( idx, flag )
int idx, flag;
{
int pxyarray[4]; /* rectangle for drawing box */
int shadow[4]; /* rectangle for box's shadow */
int x, y; /* position of box's text */
/* use the box flags to see if the box should be enabled/disabled */
if( ((boxflags[cutflag] >> (idx-SCRN1)) & 0x0001) == 0 )
vst_effects( handle, 2 );
else
vst_effects( handle, 0 );
/* get the box's coordinates */
pxyarray[0] = xwork + boxes[ idx ].x;
pxyarray[1] = ywork + boxes[ idx ].y;
pxyarray[2] = pxyarray[0] + boxes[ idx ].w;
pxyarray[3] = pxyarray[1] + boxes[ idx ].h;
/* set the shadow box coodinates */
shadow[0] = pxyarray[0] + 2;
shadow[1] = pxyarray[1] + 2;
shadow[2] = pxyarray[2] + 2;
shadow[3] = pxyarray[3] + 2;
/* draw the shadow of the box */
v_hide_c( handle );
vswr_mode( handle, 1 );
vsf_perimeter( handle, 1 );
vsf_color( handle, 1 );
vsf_interior( handle, 1 );
v_bar( handle, shadow );
/* draw it as an outline, or as selected based on the flag */
vsf_interior( handle, flag );
v_bar( handle, pxyarray );
/* print the string in the box */
x = (boxes[idx].w / 2) - ((strlen(boxes[idx].string) * gr_hwchar)/2);
x = pxyarray[0] + x;
y = pxyarray[3] - 3;
vswr_mode( handle, 3 );
v_gtext( handle, x, y, boxes[idx].string );
vswr_mode( handle, 1 );
vst_effects( handle, 0 );
v_show_c( handle, 1 );
} /* End of - draw_box() */
/************************************************************
* initialize(): *
* This routine initializes the box array and opens a window *
************************************************************/
initialize()
{
int i, a; /* miscellaneous variables */
/* tell GEM we're here, and install our DESK item... */
appl_init();
handle = graf_handle( &gr_hwchar, &gr_hhchar, &i, &i );
menu_id = menu_register( gl_apid, " The Generator..." );
rez = Getrez(); /* get the current screen resolution */
cur_screen = SCRN1; /* set the initial screen selected */
wi_handle = -1; /* indicate no window is open! */
/* initialize the box position array... */
for( a = SCRN1; a <= TO_DATA; a++ )
{
boxes[ a ].x = boxes[ a ].x * gr_hwchar;
boxes[ a ].y = (gr_hhchar/2 ) + (boxes[ a ].y * gr_hhchar);
boxes[ a ].w = boxes[ a ].w * gr_hwchar;
boxes[ a ].h = boxes[ a ].h * gr_hhchar + 3;
}
/* calculate the initial window position and dimension */
ax = 5 * gr_hwchar;
ay = 2 * gr_hhchar;
aw = boxes[TO_DATA].x+boxes[TO_DATA].w+gr_hwchar+2;
ah = boxes[TO_DATA].y+boxes[TO_DATA].h+gr_hhchar+(gr_hhchar/2)+6;
} /* End of - initialize() */
/*******************************************************
* open_vwork(): *
* This routine opens the workstation for the accessory *
*******************************************************/
open_vwork()
{
int i;
for( i = 0; i < 10; work_in[ i++ ] = 1 );
work_in[ 10 ] = 2;
v_opnvwk( work_in, &handle, work_out );
}
/*******************************************************
* open_window(): *
* This routine opens the window used for the accessory *
*******************************************************/
open_window()
{
/* create, then open the accessory window */
wi_handle = wind_create( WI_KIND, 0, 0, aw, ah );
wind_set( wi_handle, WF_NAME, "DE Image Generator", 0, 0 );
wind_open( wi_handle, ax, ay, aw, ah );
get_workarea();
}
/**********************************************************
* set_clip(): *
* This routine enables or disables the clipping rectangle *
**********************************************************/
set_clip( x, y, w, h, flag )
int x, y, w, h, flag;
{
int clip[4];
clip[0] = x;
clip[1] = y;
clip[2] = x + w;
clip[3] = y + h;
vs_clip( handle, flag, clip );
}
/*********************************************************
* rectangle intersection routines for the window redraws *
*********************************************************/
int b_intersect( bin, bout )
int bin[], bout[];
{
return r_intersect(bin[0],bin[1],bin[2],bin[3],
&bout[0],&bout[1],&bout[2],&bout[3] );
}
r_intersect( bx, by, bw, bh, ox, oy, ow, oh )
int bx, by, bw, bh, *ox, *oy, *ow, *oh;
{
int x, y, w, h;
w = minimum( bx + bw, *ox + *ow );
h = minimum( by + bh, *oy + *oh );
x = maximum( *ox, bx );
y = maximum( *oy, by );
*ox = x;
*oy = y;
*ow = w - x;
*oh = h - y;
return w > x && h > y;
}